#include "TcpServer.h"

void ignore_sigpipe()
{
    struct sigaction sa;
    memset(&sa, 0, sizeof(sa));
    sa.sa_handler = SIG_IGN;
    sigaction(SIGPIPE, &sa, NULL);
}

struct TcpServer *tcpServerInit(unsigned short port, int threadnum)
{
    // Debug("正在初始化 tcpServerInit");
    struct TcpServer *tcpserver = (struct TcpServer *)malloc(sizeof(struct TcpServer));
    // Debug("正在初始化 tcpServerInit");
    // 初始化著时间循环 epollfd e sockpairfd 4 5
    tcpserver->mainLoop = CreateEventInit();
    // Debug("正在初始化 tcpServerInit");
    tcpserver->threadNum = threadnum;
    // Debug("正在初始化 tcpServerInit");
    tcpserver->threadPool = ThreadPoolInit(tcpserver->mainLoop, tcpserver->threadNum);
    // Debug("正在初始化 tcpServerInit");
    // acceptfd =6
    tcpserver->listener = listenserInit(port);
    // Debug("正在初始化 tcpServerInit");
    return tcpserver;
}

struct Listener *listenserInit(unsigned short port)
{

    // 创建套接字
    int acceptfd = socket(AF_INET, SOCK_STREAM, 0);

    if (acceptfd == -1)
    {
        printf("accept error %d %s", errno, strerror(errno));
        exit(-1);
    }

    // 设置端口复用

    int opt = 1;
    int ret = setsockopt(acceptfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
    if (ret == -1)
    {
        printf("setsockopt error %d %s", errno, strerror(errno));
        exit(-1);
    }
    // 绑定套接字
    // int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    // addr.sin_addr.s_addr = inet_addr(INADDR_ANY); // 点分十进制转换为 网络字节序   转化为大端模式
    // addr.sin_addr.s_addr = htonl(INADDR_ANY);
    addr.sin_addr.s_addr = INADDR_ANY;

    socklen_t len = sizeof(addr);
    ret = bind(acceptfd, (struct sockaddr *)&addr, len);
    if (ret == -1)
    {
        printf("bind error %d %s", errno, strerror(errno));
        exit(-1);
    }
    // 监听套接字
    ret = listen(acceptfd, BACKLOG);
    if (ret == -1)
    {
        printf("listen error %d %s", errno, strerror(errno));
        exit(-1);
    }

    struct Listener *listener = (struct Listener *)malloc(sizeof(struct Listener));
    listener->port = port;
    listener->lfd = acceptfd;

    return listener;
}

int acceptConnection(void *arg)
{
    // Debug("我要开始连接了");
    struct TcpServer *tcpserver = (struct TcpServer *)arg;
    struct sockaddr_in clientaddr;
    socklen_t len = sizeof(clientaddr);
    int clientfd = accept(tcpserver->listener->lfd, (struct sockaddr *)&clientaddr, &len);

    struct EventLoop *evloop = takeWorkEventLoop(tcpserver->threadPool);

    Debug("start TcpConnectionInit");
    TcpConnectionInit(clientfd, evloop);
    return 0;
}

void tcpserverRun(struct TcpServer *tcpserver)
{

    ThreadPoolRun(tcpserver->threadPool);

    struct Channel *channel = ChannelInit(tcpserver->listener->lfd, ReadEvent, acceptConnection, NULL, NULL, tcpserver);

    eventAddTask(tcpserver->mainLoop, channel, ADD);

    eventLoopRun(tcpserver->mainLoop);

    
}